import sys
import numpy as np
from source.MainWindow import Ui_MainWindow
from PyQt5.Qt import Qt
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import pyqtSignal, QTimer, QStringListModel
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QApplication, QMainWindow
from utilsDemo.VideoClass import CameraVideoClass, OpenFaceClassifier, FaceRecognition, InputFace, CancelFace, \
    CompleteFaceInfoInput, OpenFile, ReadImage, DeleteImage, ModificationImage, ShowImage
from utils.utils_fit import update_dates
from DialogPane import Dialog


class MainWindow(QMainWindow, Ui_MainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.VideoClass = CameraVideoClass()
        # 定义定时器初始化
        self.Main_Qtimer_1 = QTimer()
        self.Main_Qtimer_2 = QTimer()
        self.Info_Qtimer_1 = QTimer()

        self.face = None
        self.path = None
        self.items = None
        self.detect_face = np.zeros((100, 500, 3), dtype=np.uint8)
        self.i = 0
        self.name = None
        self.setupUi(self)
        self.initUi()

    def initUi(self):
        # 定义按钮的连接
        self.pushButton.setCheckable(True)
        self.stackedWidget.setCurrentIndex(0)
        self.pushButton.clicked.connect(lambda: self.stackedWidget.setCurrentIndex(0))
        self.pushButton.clicked.connect(self.info_stop_gather)
        self.pushButton_2.clicked.connect(lambda: self.stackedWidget.setCurrentIndex(1))
        self.pushButton_2.clicked.connect(self.main_stop_gather)
        self.pushButton_3.clicked.connect(lambda: self.stackedWidget.setCurrentIndex(2))
        self.pushButton_3.clicked.connect(self.main_stop_gather)
        self.pushButton_3.clicked.connect(self.info_stop_gather)
        self.pushButton_4.clicked.connect(lambda: self.stackedWidget.setCurrentIndex(3))
        self.pushButton_4.clicked.connect(self.main_stop_gather)
        self.pushButton_4.clicked.connect(self.info_stop_gather)

        # 定义相机类初始化
        self.VideoClass.CameraInit()

        self.label.setScaledContents(True)
        self.label_2.setScaledContents(True)
        self.label_3.setScaledContents(True)
        self.label_4.setScaledContents(True)
        self.label_5.setScaledContents(True)
        self.label_14.setScaledContents(True)

        # 定义定时器的连接
        self.Main_Qtimer_1.timeout.connect(self.MainShowMV)
        self.Main_Qtimer_2.timeout.connect(self.MatchFace)
        self.Info_Qtimer_1.timeout.connect(self.InfoShowMV)

    # 定义退出系统槽函数
    def exit_system(self):
        self.VideoClass.CaptureCamera()
        self.close()

    # 定义主界面开始采集槽函数
    def main_start_gather(self):
        self.Main_Qtimer_1.start(35)

    # 定义主界面显示槽函数
    def MainShowMV(self):
        frame = self.VideoClass.CaptureCamera()
        if frame is not None:
            frame, self.face = OpenFaceClassifier(frame)
            if self.face is not None:
                self.Main_Qtimer_2.start(35)
                self.detect()
            frame = QImage(frame.data, frame.shape[1], frame.shape[0], frame.shape[1] * 3, QImage.Format_RGB888)
            self.label.setPixmap(QPixmap.fromImage(frame))
        else:
            QtWidgets.QMessageBox.question(self, "提示", "未连接到相机请检查连接！", )
            self.Main_Qtimer_1.stop()

    # 将检测出来的人脸显示出来
    def detect(self):
        if self.face is not None:
            for img in self.face:
                self.detect_face[0:100, self.i * 100:(self.i + 1) * 100] = img
                self.i += 1
                if self.i == 5:
                    self.i = 0
            detect_face = QImage(self.detect_face.data, self.detect_face.shape[1], self.detect_face.shape[0],
                                 self.detect_face.shape[1] * 3, QImage.Format_RGB888)
            self.label_2.setPixmap(QPixmap.fromImage(detect_face))

    # 将检测出来的人脸经过模型预测后显示出来
    def MatchFace(self):
        if self.face is not None:
            for img in self.face:
                match_face = FaceRecognition(img)
                if match_face is not None:
                    match_face = QImage(match_face.data, match_face.shape[1], match_face.shape[0],
                                        match_face.shape[1] * 3,
                                        QImage.Format_RGB888)
                    self.label_3.setPixmap(QPixmap.fromImage(match_face))

    # 定义主界面停止采集槽函数
    def main_stop_gather(self):
        self.Main_Qtimer_1.stop()
        self.Info_Qtimer_1.stop()

    # 定义信息采集开始采集槽函数
    def info_start_gather(self):
        self.Info_Qtimer_1.start(35)

    # 定义信息采集主界面显示槽函数
    def InfoShowMV(self):
        frame = self.VideoClass.CaptureCamera()
        if frame is not None:
            frame, self.face = OpenFaceClassifier(frame)
            frame = QImage(frame.data, frame.shape[1], frame.shape[0], frame.shape[1] * 3, QImage.Format_RGB888)
            self.label_4.setPixmap(QPixmap.fromImage(frame))
        else:
            QtWidgets.QMessageBox.question(self, "提示", "未连接到相机请检查连接！", )
            self.Info_Qtimer_1.stop()

    # 定义显示将录入人脸图片
    def ShowInputFace(self):
        if self.path is not None:
            img = ShowImage(self.path)
            img = QImage(img.data, img.shape[1], img.shape[0], img.shape[1] * 3, QImage.Format_RGB888)
            self.label_5.setPixmap(QPixmap.fromImage(img))

    # 定义信息采集停止采集槽函数
    def info_stop_gather(self):
        self.Info_Qtimer_1.stop()

    # 定义完成信息录入
    def complete__input(self):
        if self.path is not None:
            CompleteFaceInfoInput(self.path)
            QtWidgets.QMessageBox.question(self, "提示", "人脸数据库更新完毕！", )
            self.path = None

    # 定义确定人脸信息录入槽函数
    def info_confirm(self):
        if self.lineEdit.text() == '' or self.lineEdit_2.text() == '':
            QtWidgets.QMessageBox.warning(self, "警告", "请输入姓名和学号", )
        else:
            self.name = self.lineEdit.text() + self.lineEdit_2.text()
            self.path = InputFace(self.face, self.name)
            self.ShowInputFace()

    # 定义取消人脸信息录入槽函数
    def info_cancel(self):
        if self.path is not None:
            CancelFace(self.path)

    # 打开人脸图片文件夹
    def open_file(self):
        self.items = OpenFile()
        listModel = QStringListModel()
        listModel.setStringList(self.items)
        self.listView.setModel(listModel)
        self.listView.clicked.connect(self.onClickedListView)

    # 定义选择的图片
    def onClickedListView(self, item):
        if self.items is not None:
            img = ReadImage(self.items[item.row()])
            img = QImage(img.data, img.shape[1], img.shape[0], img.shape[1] * 3, QImage.Format_RGB888)
            self.label_14.setPixmap(QPixmap.fromImage(img))

    # 定义删除选择的图片
    def delete_file(self):
        index = self.listView.currentIndex().row()
        if index != -1:
            self.items = DeleteImage(self.items[index])
            listModel = QStringListModel()
            listModel.setStringList(self.items)
            self.listView.setModel(listModel)
        else:
            QtWidgets.QMessageBox.warning(self, "警告", "请先打开文件夹以及选择图片！！！", )

    # 定义修改图片名称
    def modification_photos(self):
        index = self.listView.currentIndex().row()
        if index == -1:
            QtWidgets.QMessageBox.warning(self, "警告", "请先打开文件夹以及选择图片！！！", )
        else:
            Dialog.show()
            Dialog.modification_info_signal[str].connect(self.ConfirmModification)

    # 定义确定修改图片信息槽函数
    def ConfirmModification(self, event):
        index = self.listView.currentIndex().row()
        if event != '' and index != -1:
            self.items = ModificationImage(index, self.items, event)
            listModel = QStringListModel()
            listModel.setStringList(self.items)
            self.listView.setModel(listModel)

    # 定义更新数据库
    def update_database(self):
        update_dates()
        QtWidgets.QMessageBox.question(self, "提示", "人脸数据库更新完毕！", )

    def setup_confirm(self):
        pass

    def setup_cancel(self):
        pass

    def setup_choice_files(self):
        pass

    def closeEvent(self, event):
        result = QtWidgets.QMessageBox.question(self, "标题", "是否确定关闭！！！",
                                                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
        if result == QtWidgets.QMessageBox.Yes:
            event.accept()
            self.VideoClass.ExitCamera()
        else:
            event.ignore()


if __name__ == '__main__':
    QtCore.QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
    app = QApplication(sys.argv)
    main = MainWindow()
    Dialog = Dialog()
    main.show()
    sys.exit(app.exec_())
